<template>
    <el-form class="spec-list" @keyup.enter.stop label-width="160">
        <!-- 模板 -->
        <view v-if="props.specTemplateConfig.enable">
            <el-form-item :label="t('shop.goodsSpec.specTemplate')" label-width="160">
                <div>
                    <el-select
                        v-model="state.specTemplateValue"
                        value-key="id"
                        filterable
                        :placeholder="t('shop.goodsSpec.selectSpecTemplate')"
                        style="width: 300px"
                        @change="onChangeTemplateValue"
                        clearable
                        @clear="clearSpecList"
                    >
                        <el-option v-for="item in props.specTemplateConfig?.data" :key="item.id" :label="item.name" :value="item" />
                    </el-select>
                    <div>
                        <el-text type="danger">{{
                            t('shop.goodsSpec.The content of the specification template will cover all specification names and values of the product')
                        }}</el-text>
                    </div>
                </div>
            </el-form-item>
        </view>
        <!-- 属性 -->
        <el-form-item :label="t('shop.goodsSpec.specAttr')" label-width="160">
            <div>
                <el-button type="primary" @click="addSpecRow" class="spec-list-attr">
                    {{ t('shop.goodsSpec.addSpecAttr') }}
                </el-button>
            </div>
            <div class="spec-list-item" v-for="(item, index) in state.specData.specList" :key="index">
                <div class="spec-list-item-main">
                    <div class="spec-list-item-layout">
                        <span class="span">{{ t('shop.goodsSpec.attrName') }}</span>
                        <view style="display: flex">
                            <el-input size="small" v-model="item.name" class="input" :autosize="true" />
                            <Icon name="el-icon-Delete" @click="removeSpecRow(index)" class="spec-list-item-removeIcon" />
                        </view>
                    </div>
                    <div class="spec-list-item-layout">
                        <span class="span">{{ $t('shop.goodsSpec.attrValue') }}</span>
                        <div class="spec-list-item-tags">
                            <view>
                                <el-tag
                                    class="spec-list-item-tag"
                                    closable
                                    v-for="(subitem, i) in item.value"
                                    :key="i"
                                    @close="removeSpecAttr(index, i)"
                                    hit
                                >
                                    <view style="display: flex; align-items: center">
                                        <Icon
                                            name="el-icon-Edit"
                                            color="#8595F4"
                                            size="15"
                                            style="margin-right: 10px"
                                            @click="editSpecAttr(index, i)"
                                        />
                                        {{ subitem }}
                                    </view>
                                </el-tag>
                                <el-button size="small" icon="el-icon-Plus" @click="addSpecAttr(index)"></el-button>
                            </view>
                        </div>
                    </div>
                </div>
            </div>
            <div class="spec-list-head">
                <el-text type="warning">{{ t('shop.goodsSpec.buildSpecTip') }}</el-text>
            </div>
        </el-form-item>

        <!-- SKU -->
        <el-form-item :label="t('shop.goodsSpec.skuAttr')" label-width="160">
            <div class="spec-list-sku-container">
                <div class="spec-list-sku-container-button">
                    <el-button type="primary" @click="buildSpecData" class="spec-list-head">{{ t('shop.goodsSpec.buildSpecSku') }}</el-button>
                </div>
            </div>
            <div style="display: flex; flex-wrap: wrap; margin-bottom: 15px">
                <el-text style="margin-right: 10px">{{ t('shop.goodsSpec.batchSetSku') }}: </el-text>
                <div v-for="(item, key) in state.skuField" :key="key" style="margin-right: 10px; padding-bottom: 5px">
                    <el-input-number
                        v-if="((item.attr && item.attr.type) || 'input-number') === 'input-number'"
                        v-model="item.value"
                        style="width: 140px"
                        :placeholder="item.label"
                        controls-position="right"
                        v-bind="item.attr"
                    />
                    <el-input v-else v-model="item.value" style="width: 140px" :placeholder="item.label" v-bind="item.attr" />
                </div>
                <el-button style="margin-bottom: 5px" @click="batchSetskuField">{{ t('shop.goodsSpec.batchSetting') }}</el-button>
            </div>
            <el-table border :data="state.specData.skuList" class="spec-list-table">
                <el-table-column :label="t('shop.goodsSpec.spec')" align="center" prop="spec" show-overflow-tooltip min-width="145">
                    <template #header="{ column }">
                        <el-tooltip :content="column.label" placement="top-start">
                            <span>{{ column.label }}</span>
                        </el-tooltip>
                    </template>
                    <template #default="{ row }">
                        <el-text style="white-space: pre-line">{{ row.spec.replace(/;/g, '\n') }}</el-text>
                    </template>
                </el-table-column>
                <el-table-column :label="t('shop.goodsSpec.specImg')" align="center" width="170" flexible>
                    <template #default="{ row }">
                        <view>
                            <baUpload v-model="row.image" type="image" :hide-image-plus-on-over-limit="true" class="spec-list-table-image" />
                        </view>
                    </template>
                </el-table-column>
                <el-table-column v-for="(item, key) in props.skuField" :key="key" :label="item.label" align="center" width="145">
                    <template #header="{ column }">
                        <span>{{ column.label }}</span>
                    </template>
                    <template #default="{ row }">
                        <view v-if="((item.attr && item.attr.type) || 'input-number') === 'input-number'">
                            <el-input-number size="small" v-bind="item.attr" v-model="row[key]" />
                        </view>
                        <view v-else>
                            <el-input size="small" v-bind="item.attr" v-model="row[key]" />
                        </view>
                    </template>
                </el-table-column>
            </el-table>
        </el-form-item>
    </el-form>
</template>

<script setup lang="ts">
import { ElMessageBox, ElMessage } from 'element-plus'
import { reactive, watch } from 'vue'
import baUpload from '/@/components/baInput/components/baUpload.vue'
import { i18n } from '/@/lang'

const { t } = i18n.global

// 规格属性
type specList = {
    name: string
    value: string[]
}
// 组装后的规格信息
type typeSpec = {
    specList: specList[]
    skuList: object[]
}
// SkU字段
type typeskuFieldValue = {
    [key: string]: { label: string; type: string } & any
}
// 规格模板
type typeSpecTemplateData = { id: number; name: string; value: specList[] }

interface Prop {
    // 规格数据
    modelValue: typeSpec
    // SKU自定义字段
    skuField?: typeskuFieldValue
    // 规格模板配置
    specTemplateConfig?: {
        // 是否启用规格模板
        enable?: boolean
        // 规格模板数据
        data?: typeSpecTemplateData[]
    }
}

const props = withDefaults(defineProps<Prop>(), {
    modelValue: () => ({
        specList: [
            {
                name: '',
                value: [],
            },
        ],
        skuList: [],
    }),
    skuField: () => ({}),
    specTemplateConfig: () => ({
        enable: false,
        specTemplateData: [],
    }),
})

const state = reactive({
    specData: props.modelValue,
    specTemplateValue: '',
    skuField: props.skuField,
})

const emits = defineEmits<{
    (e: 'update:modelValue', value: typeSpec): void
}>()

emits('update:modelValue', state.specData)

// 切换规格模板触发
const onChangeTemplateValue = (val: any) => {
    if (!val || !val.value) return
    const templateValue = val.value
    state.specData.specList = templateValue.map((obj: any) => ({
        name: obj.name || '',
        value: obj.value || [],
    }))
}

// 添加规格行
const addSpecRow = () => {
    state.specData.specList.push({
        name: '',
        value: [],
    })
}

// 删除规格行
const removeSpecRow = (i: number) => {
    const specListLength = state.specData.specList.length
    if (specListLength === 1) {
        ElMessage({ message: t('shop.goodsSpec.Keep at least one valid specification group'), type: 'error' })
        return
    }
    ElMessageBox.confirm(
        t('shop.goodsSpec.Are you sure you want to delete the data for this specification group? This operation cannot be restored'),
        t('shop.goodsSpec.warning'),
        {
            confirmButtonText: t('shop.goodsSpec.confirm'),
            cancelButtonText: t('shop.goodsSpec.cancel'),
            type: 'warning',
        }
    )
        .then(() => {
            state.specData.specList.splice(i, 1)
        })
        .catch(() => {})
}

// 添加规格属性值
const addSpecAttr = (index: number) => {
    ElMessageBox.prompt(t('shop.goodsSpec.inputSpecValue'), t('shop.goodsSpec.addSpecValue'), {
        confirmButtonText: t('shop.goodsSpec.confirm'),
        cancelButtonText: t('shop.goodsSpec.cancel'),
        inputPattern: /^\S+$/,
        inputErrorMessage: t('shop.goodsSpec.The specification value cannot be empty'),
        closeOnClickModal: false,
    })
        .then(({ value }: { value: string }) => {
            value = value.trim()
            state.specData.specList[index].value.push(value)
        })
        .catch(() => {})
}

// 编辑规格属性值
const editSpecAttr = (index: number, key: number) => {
    ElMessageBox.prompt('', t('shop.goodsSpec.editSpecValue'), {
        confirmButtonText: t('shop.goodsSpec.confirm'),
        cancelButtonText: t('shop.goodsSpec.cancel'),
        inputPattern: /^\S+$/,
        inputErrorMessage: t('shop.goodsSpec.The specification value cannot be empty'),
        closeOnClickModal: false,
        inputValue: state.specData.specList[index].value[key],
    })
        .then(({ value }: { value: string }) => {
            value = value.trim()
            state.specData.specList[index].value[key] = value
        })
        .catch(() => {})
}

// 删除规格属性值
const removeSpecAttr = (index: number, key: number) => {
    const valueLength = state.specData.specList[index].value.length
    if (valueLength === 1) {
        ElMessage({ message: t('shop.goodsSpec.Keep at least one valid specification'), type: 'error' })
        return
    }
    ElMessageBox.confirm(
        t('shop.goodsSpec.Are you sure you want to delete this specification value? This operation cannot be restored'),
        t('shop.goodsSpec.warning'),
        {
            confirmButtonText: t('shop.goodsSpec.confirm'),
            cancelButtonText: t('shop.goodsSpec.cancel'),
            type: 'warning',
        }
    )
        .then(() => {
            state.specData.specList[index].value.splice(key, 1)
        })
        .catch(() => {})
}

// 生成规格数据
const buildSpecData = () => {
    const specList = state.specData.specList
    const specListLength = specList.length

    if (specListLength === 0 || specList.every((item) => item.name === '' || item.value.length === 0)) {
        ElMessage({ message: t('shop.goodsSpec.Specification name or specification value cannot be empty'), type: 'error' })
        return
    }

    const table: any[] = []
    const attrValueAry: any[] = []
    const arr: any[] = []

    const tmpspecData = specList.filter((d) => d.name !== '' && d.value.length > 0)

    if (!tmpspecData || tmpspecData.length === 0) {
        return []
    }

    tmpspecData.forEach((item) => {
        item.name = item.name.trim()
        attrValueAry.push(item.value)
    })

    const addSpecValue = (specarr: any[] = [], i: number) => {
        for (let j = 0; j < attrValueAry[i].length; j++) {
            if (i < attrValueAry.length - 1) {
                specarr[i] = attrValueAry[i][j]
                addSpecValue(specarr, i + 1)
            } else {
                arr.push([...specarr, attrValueAry[i][j]])
            }
        }
    }

    addSpecValue([], 0)
    arr.forEach((item: any) => {
        let findItem: any
        let tableItem: object

        let specs: string[] = []

        item.forEach((d: { value: string }, idx: number) => {
            specs.push(`${tmpspecData[idx].name}:${d}`)
        })
        const spec = specs.join(';')

        findItem =
            state.specData.skuList.find((item: any) => {
                return spec.includes(item.spec)
            }) || {}

        tableItem = Object.assign(
            Object.keys(props.skuField).reduce(
                (obj, key: string) => {
                    obj[key] = 0
                    return obj
                },
                {} as { [key: string]: any }
            ),
            findItem,
            {
                spec,
            },
            {
                image: findItem.hasOwnProperty('image') ? findItem.image : '',
            }
        )

        table.push(tableItem)
    })

    state.specData.skuList = table

    emits('update:modelValue', state.specData)
}

// 批量设置规格字段
const batchSetskuField = () => {
    if (state.specData.skuList.length === 0) {
        ElMessage.error(t('shop.goodsSpec.Please generate SKU data first'))
        return
    }
    const data = state.skuField
    const batchFields: any = {}
    for (let key in data) {
        if (data.hasOwnProperty(key)) {
            const value = data[key].value
            if (value !== undefined && value !== null) {
                batchFields[key] = data[key]
            }
        }
    }
    state.specData.skuList.forEach((item: any) => {
        for (let key in batchFields) {
            const type = batchFields[key].attr?.type || 'input-number'
            const value = batchFields[key].value
            if (type === 'input-number') {
                item[key] = Number(value)
            } else {
                item[key] = value
            }
        }
    })
}

//清空规格属性
const clearSpecList = () => {
    state.specData.specList.map((item) => {
        item.name = ''
        item.value = []
    })
}

watch(
    () => props.modelValue,
    (newVal) => {
        state.specTemplateValue = ''
        state.specData = { ...newVal }

        emits('update:modelValue', newVal)
    }
)
</script>

<style lang="scss" scoped>
.spec-type {
    margin-bottom: 20px;
}

.spec-list {
    margin-bottom: 20px;

    &-attr {
        margin-bottom: 20px;
    }

    &-item {
        width: 70%;
    }

    &-head {
        margin-bottom: 15px;
    }

    &-sku-container {
        display: flex;
        align-items: center;
        justify-content: center;

        &-button {
            margin-right: 10px;
        }

        &-batch {
            margin-bottom: 15px;
        }
    }

    &-table {
        word-break: nowrap;

        &-icon {
            margin: 5px;
            align-items: center;
            cursor: pointer;
        }
    }

    &-item {
        width: 160%;
        display: flex;
        align-items: center;
        border-radius: 5px;
        margin-bottom: 10px;
        padding: 20px 50px 50px 20px;

        @media screen and (min-width: 240px) {
            border: 1px solid #eee;
        }

        &-main {
            flex: 1;
        }
        &-removeIcon {
            margin-left: 20px;
            color: #f56c6c;
            cursor: pointer;
        }
        &-layout {
            display: flex;
            align-items: center;
            margin-bottom: 30px;
            flex-wrap: wrap;

            &:last-child {
                margin-bottom: 0;
            }
            .input {
                width: auto;
            }
            .span {
                font-size: 14px;
                font-weight: bold;
                margin-right: 10px;
            }
        }
        &-tag {
            margin-right: 10px;
            // cursor: pointer;
        }
        .el-tag__content {
            display: flex;
        }
        &-text {
            color: red;
        }
    }
}

:deep(.el-table .cell) {
    word-break: keep-all;
}

// 修复预览图片时表格样式重叠
:deep(.el-table .el-table__cell) {
    position: relative;
    z-index: auto;
}
.el-form-item__label {
    width: auto;
}
</style>
